//
//  XIVector.h
//  XIEngine
//
//  Created by Balazs Faludi on 08.11.09.
//  Copyright 2009 Universität Basel. All rights reserved.
//

#import <Foundation/Foundation.h>
#import "XIEngine.h"

// Vector structure used in XIEngine.
typedef struct XIVector {
	XIFloat x, y;
} XIVector;

// Alternative names.
typedef XIVector XIVec;
typedef XIVector XIV;
//typedef XIVector xiVec;

static const XIVector XIVectorZero = {0.0f, 0.0f};

static inline XIVector
xiv(const XIFloat x, const XIFloat y)
{
	XIVector v = {x, y};
	return v;
}

static inline XIVector
xivadd(const XIVector v1, const XIVector v2)
{
	return xiv(v1.x + v2.x, v1.y + v2.y);
}

static inline XIVector
xivneg(const XIVector v)
{
	return xiv(-v.x, -v.y);
}

static inline XIVector
xivsub(const XIVector v1, const XIVector v2)
{
	return xiv(v1.x - v2.x, v1.y - v2.y);
}

static inline XIVector
xivmult(const XIVector v, const XIFloat s)
{
	return xiv(v.x * s, v.y * s);
}

static inline XIFloat
xivdot(const XIVector v1, const XIVector v2)
{
	return v1.x * v2.x + v1.y * v2.y;
}

static inline XIFloat
xivcross(const XIVector v1, const XIVector v2)
{
	return v1.x * v2.y - v1.y * v2.x;
}

static inline XIVector
xivperp(const XIVector v)
{
	return xiv(-v.y, v.x);
}

static inline XIVector
xivrperp(const XIVector v)
{
	return xiv(v.y, -v.x);
}

static inline XIVector
xivproject(const XIVector v1, const XIVector v2)
{
	return xivmult(v2, xivdot(v1, v2) / xivdot(v2, v2));
}

static inline XIVector
xivrotate(const XIVector v1, const XIVector v2)
{
	return xiv(v1.x * v2.x - v1.y * v2.y, v1.x * v2.y + v1.y * v2.x);
}

static inline XIVector
xivunrotate(const XIVector v1, const XIVector v2)
{
	return xiv(v1.x * v2.x + v1.y * v2.y, v1.y * v2.x - v1.x * v2.y);
}

static inline XIFloat
xivangle2(const XIVector v1, const XIVector v2)
{
	return atan2f(v2.y, v2.x) - atan2f(v1.y, v1.x);
}

static inline XIFloat
xivangle(const XIVector v)
{
	return xivangle2(v, xiv(1, 0));
}

static inline XIVector
xivpol(XIFloat radius, XIFloat angle)
{
	XIVector v = {radius * cosf(angle), radius * sinf(angle)};
	return v;
}

static inline CGPoint
xivToCGPoint(XIVector v)
{
	return CGPointMake(v.x, v.y);
}


XIFloat xivlength(const XIVector v);
XIFloat xivlengthsq(const XIVector v); // no sqrt() call
XIVector xivnormalize(const XIVector v);
XIVector xivforangle(const XIFloat a); // convert radians to a normalized vector
XIFloat xivtoangle(const XIVector v); // convert a vector to radians
XIVector xivsetangle(XIVector v, XIFloat newAngle);
XIVector xivsetlength(XIVector v, XIFloat newLength);
NSString *xivstr(const XIVector v); // get a string representation of a vector
